package com.intramirror.product.controller;

import com.intramirror.core.common.response.Response;
import com.intramirror.core.common.response.StatusCode;
import com.intramirror.product.entity.PriceChangeRule;
import com.intramirror.product.service.IPriceRuleService;
import com.intramirror.product.utils.StringUtils;
import com.intramirror.product.vo.BasePriceRuleChangeVO;
import com.intramirror.utils.transform.JsonTransformUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class PriceRuleController {
    private final static Logger LOGGER = LoggerFactory.getLogger(PriceRuleController.class);

    @Autowired
    IPriceRuleService priceRuleService;

    @PostMapping("/im/algorithm/refresh/{algorithmId}")
    public Response refreshAlgorithm(@PathVariable(value = "algorithmId") Long algorithmId) throws Exception {
        long start = System.currentTimeMillis();
        priceRuleService.refreshSnapshotPrice(algorithmId);
        long end = System.currentTimeMillis();
        LOGGER.info("Finish refresh algorithm, it takes {}ms.", end - start);
        return Response.status(StatusCode.SUCCESS).data("Ok");
    }

    @PostMapping("/im/algorithm/refresh/{algorithmId}/{ruleId}")
    public Response refreshRule(@PathVariable(value = "algorithmId") Long algorithmId, @PathVariable(value = "ruleId") Long ruleId) throws Exception {
        long start = System.currentTimeMillis();
        priceRuleService.refreshSnapshotPrice(algorithmId, ruleId);
        long end = System.currentTimeMillis();
        LOGGER.info("Finish refresh algorithm {} rule {}, it takes {}ms.", algorithmId, ruleId, end - start);
        return Response.status(StatusCode.SUCCESS).data("Ok");
    }

    // @PostMapping("/boutique/priceRule") not finish
    public Response modifyPriceChangeRule(@RequestBody BasePriceRuleChangeVO priceRuleChangeVO) {
        priceRuleService.changePriceRule(priceRuleChangeVO);
        return Response.status(StatusCode.SUCCESS).data(priceRuleChangeVO.getType());
    }

    @PostMapping("/priceChangeRule/changePreviewByBoutique/{ruleId}/{previewStatus}/{flag}")
    public Response changePreviewByBoutique(@PathVariable(value = "ruleId") Long ruleId, @PathVariable(value = "previewStatus") Integer previewStatus,
            @PathVariable(value = "flag") int flag) {
        long start = System.currentTimeMillis();
        try {
            synchronized (this) {
                priceRuleService.updateProductPreviewPriceByBoutique(ruleId, previewStatus, flag);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("error message : " + e.getMessage());
            return Response.status(StatusCode.FAILURE).data("error message : " + e.getMessage());
        }

        long end = System.currentTimeMillis();
        LOGGER.info("Finish changePreviewByBoutique ruleId {} previewStatus {}  flag {}, it takes {}ms.", ruleId, previewStatus, flag, end - start);
        return Response.status(StatusCode.SUCCESS).data("Ok");
    }

    @PostMapping("/priceChangeRule/boutique/{priceChangeRuleId}/{flag}")
    public Response changePreviewByBoutique(@PathVariable(value = "priceChangeRuleId") Long priceChangeRuleId, @PathVariable(value = "flag") String flag) {
        LOGGER.info("Start running BOUTIQUE discounts,price_change_rule_id {}", priceChangeRuleId);
        long start = System.currentTimeMillis();

        PriceChangeRule pcrModel = priceRuleService.selectByPrimaryKey(priceChangeRuleId);

        if (pcrModel.getStatus() != 1) {
            LOGGER.info("Start running IM discounts Error,price_change_rule_id {}", priceChangeRuleId);
            return Response.status(StatusCode.FAILURE).data("不允许执行非Pending的Boutique折扣");
        }

        if (StringUtils.isNotEmpty(flag) && flag.equalsIgnoreCase("all")) {
            priceChangeRuleId = null;
        }

        try {
            synchronized (this) {
                LOGGER.info("syncBoutiqueStart,vendorId:{},categoryType:{},priceChangeRuleId:{}", pcrModel.getVendorId(), pcrModel.getCategoryType(),
                        priceChangeRuleId);
                priceRuleService.synUpdateProductPrice(pcrModel.getVendorId(), pcrModel.getCategoryType(), priceChangeRuleId);
                LOGGER.info("syncBoutiqueEnd,vendorId:{},categoryType:{},priceChangeRuleId:{}", pcrModel.getVendorId(), pcrModel.getCategoryType(),
                        priceChangeRuleId);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("error message : " + e.getMessage());
            return Response.status(StatusCode.FAILURE).data("error message : " + e.getMessage());
        }

        long end = System.currentTimeMillis();
        LOGGER.info("End running BOUTIQUE discounts,price_change_rule_id {} flag {}, it takes {}ms.", priceChangeRuleId, flag, end - start);

        return Response.status(StatusCode.SUCCESS).data("Ok");
    }

    @GetMapping("/priceChangeRule/run/{type}")
    public Response run(@PathVariable(name = "type") String type) {
        long start = System.currentTimeMillis();
        LOGGER.info("start run price rule by type:{}", type);
        try {
            Calendar startCalendar = Calendar.getInstance();
            Map<String, Object> params = new HashMap<>();
            params.put("startTime", DateFormatUtils.format(startCalendar.getTime(), "yyyy-MM-dd HH:mm:00"));
            params.put("endTime", DateFormatUtils.format(startCalendar.getTime(), "yyyy-MM-dd HH:mm:59"));

            synchronized (this) {
                LOGGER.info("start selectNowActiveRule,{},params:{}", type, JsonTransformUtil.toJson(params));
                List<Map<String, Object>> activeRules = priceRuleService.selectNowActiveRule(params);

                if (CollectionUtils.isNotEmpty(activeRules)) {
                    LOGGER.info("end selectNowActiveRule,{},params:{},activeRules:{}", type, JsonTransformUtil.toJson(params),
                            JsonTransformUtil.toJson(activeRules));
                    priceRuleService.synUpdateProductPriceByValidFrom(params.get("startTime").toString(), params.get("endTime").toString());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("Execution of discounts,e:{}", e);
        }
        long end = System.currentTimeMillis();
        LOGGER.info("end run price rule by type:{},execution time : {}", type, (end - start));
        return Response.success();
    }

}
